#include "QueryPacket.h"

QueryPacket::QueryPacket(){}
QueryPacket::~QueryPacket(){}

std::string QueryPacket::toString(){
	std::string info;
	info += "The query ID is:" + iToString(query_id) +"\n";
	info += "The total subquery is: " +iToString(subquery_size) + "\n";
	info += "Now it is in the " + iToString(current_subquery)+ " subquery.\n";
	info += "The whole query is: " + whole_query;
	return info;
}
std::string QueryPacket::iToString(int i){
	std::ostringstream i_s;
	i_s <<i;
	return i_s.str();
}

QueryPacket::QueryPacket(std::string f){
	fileName =f;
}

void QueryPacket::setFileName(std::string f){
	fileName =f;
}

void QueryPacket::readFormFile(){
	QFile resultFile(fileName.c_str());
	std::cout << fileName << std::endl;
    if (!resultFile.open(QIODevice::ReadOnly | QIODevice::Text))
         std::cout << "error opening file" << std::endl;
    QTextStream in(&resultFile);
    while (!in.atEnd()) {
    	data_qstr=in.readLine();
    	data_list=data_qstr.split("|");
    }
	query_id=data_list[0].toInt();
	subquery_size=data_list[1].toInt();
	current_subquery=data_list[2].toInt();
	whole_query=data_list[3].toStdString();
	for(int index=0;index<subquery_size;index++){
		sub_query.push_back(data_list[index+4].toStdString());
	}
	for(int index=0;index<subquery_size;index++){
		QStringList coordinate;
		GateWay dest;
		coordinate=data_list[index+4+subquery_size].split(",");
		for(int i=0;i<3;i++)
			dest.m[i]=coordinate[i].toInt();
		destination.push_back(dest);
	}
	variable_size = data_list[4+subquery_size+subquery_size].toInt();
	for(int index=0;index<variable_size;index++){
		variables.push_back(data_list[5+subquery_size+subquery_size+index].toStdString());
	}
	for(int index=0;index<subquery_size;index++){
		QStringList subquery_variables_qlist;
		subquery_variables_qlist=data_list[5+subquery_size+subquery_size+variable_size+index].split(",");
		std::vector<std::string> temp_subquery_variables;
		for(int i=0;i<3;i++){
			temp_subquery_variables.push_back(subquery_variables_qlist[i].toStdString());
		}
		subquery_variables.push_back(temp_subquery_variables);
//		std::cout << data_list[5+subquery_size+subquery_size+variable_size+index].toStdString() << std::endl;
	}
	for(int index=0;index<subquery_size;index++){
		QStringList pattern_qlist;
		pattern_qlist=data_list[5+subquery_size+subquery_size+subquery_size+variable_size+index].split(",");
		TriplePattern temp_pattern;
		for(int i=0;i<3;i++)
			temp_pattern.pattern[i]=pattern_qlist[i].toInt();
		subquery_patterns.push_back(temp_pattern);
//		std::cout << data_list[5+subquery_size+subquery_size+variable_size+index].toStdString() << std::endl;
	}
	ans_size=data_list[5+subquery_size+subquery_size+subquery_size+variable_size+subquery_size].toInt();
//	std::cout << "ans_size: " << ans_size << std::endl;
	for(int index=0;index<ans_size; index++){
		Binding binding;
		NTuple tuple;
		QStringList binding_qlist;
		std::cout << data_list[6+subquery_size+subquery_size+subquery_size+variable_size+subquery_size+index].toStdString() << std::endl;
		binding_qlist=data_list[6+subquery_size+subquery_size+subquery_size+variable_size+subquery_size+index].split(",");
		for(int i=0;i<binding_qlist.size();i++){
			QStringList element_qlist;
			element_qlist=binding_qlist[i].split("=");
			binding.variableName=element_qlist[0].toStdString();
			binding.value = element_qlist[1].toStdString();
			tuple.addBinding(binding);
		}
		partial_ans.push_back(tuple);
	}
//	std::cout << "the size of partial ans is: " << partial_ans.size() << std::endl;
//    std::cout << data_qstr.toStdString() << std::endl;
	resultFile.close();
}

/////////////////////////////////////////////////////////////////////
//			resultFile data structure
//	  | query_ID | subquery_size | current_subquery_num |  whole_query |
//    | query 1..|....query n	 | coordinate 1  ...| ... coordinate n |
//    | variable_size | variable 1 ...|... variable n | clause_element_1-1 | clause_ele_1-2 | clause_ele_1-3|...
//    | pattern 1|....pattern n  | partial_ans_1....|... partial_ans_n |
//
////////////////////////////////////////////////////////////////////

void QueryPacket::writetoFile(){
	QFile resultFile(fileName.c_str());
	std::cout << "Begin to write to file: "<<fileName << std::endl;
    if (!resultFile.open(QIODevice::WriteOnly))
         std::cout << "error opening file" << std::endl;
    resultFile.write(iToString(query_id).c_str());
    resultFile.write("|");
    resultFile.write(iToString(subquery_size).c_str());
    resultFile.write("|");
    resultFile.write(iToString(current_subquery).c_str());
    resultFile.write("|");
    resultFile.write(whole_query.c_str());
    resultFile.write("|");
    std::vector<std::string>::iterator subquery_beg=sub_query.begin();
    std::vector<std::string>::iterator subquery_end=sub_query.end();
    for(std::vector<std::string>::iterator it=subquery_beg;it!=subquery_end;it++){
    	resultFile.write((*it).c_str());
    	resultFile.write("|");
    }
    std::vector<GateWay>::iterator dest_beg=destination.begin();
    std::vector<GateWay>::iterator dest_end=destination.end();
    for(std::vector<GateWay>::iterator it=dest_beg;it!=dest_end;it++){
    	resultFile.write(iToString(*((*it).m+0)).c_str());
    	resultFile.write(",");
    	resultFile.write(iToString(*((*it).m+1)).c_str());
    	resultFile.write(",");
    	resultFile.write(iToString(*((*it).m+2)).c_str());
    	resultFile.write("|");
    }
    resultFile.write(iToString(variable_size).c_str());
    resultFile.write("|");
    std::vector<std::string>::iterator variables_beg=variables.begin();
    std::vector<std::string>::iterator variables_end=variables.end();
    for(std::vector<std::string>::iterator it=variables_beg;it!=variables_end;it++){
    	resultFile.write((*it).c_str());
    	resultFile.write("|");
    }
    std::vector<std::vector<std::string> >::iterator subquery_variables_beg= subquery_variables.begin();
    std::vector<std::vector<std::string> >::iterator subquery_variables_end=subquery_variables.end();
    for(std::vector<std::vector<std::string> >::iterator it=subquery_variables_beg;it!=subquery_variables_end;it++){
    	resultFile.write((*it).at(0).c_str());
    	resultFile.write(",");
    	resultFile.write((*it).at(1).c_str());
    	resultFile.write(",");
    	resultFile.write((*it).at(2).c_str());
    	resultFile.write("|");
    }
    std::vector<TriplePattern>::iterator pattern_beg=subquery_patterns.begin();
    std::vector<TriplePattern>::iterator pattern_end=subquery_patterns.end();
    for(std::vector<TriplePattern>::iterator it=pattern_beg;it!=pattern_end;it++){
    	resultFile.write(iToString(*((*it).pattern+0)).c_str());
    	resultFile.write(",");
    	resultFile.write(iToString(*((*it).pattern+1)).c_str());
    	resultFile.write(",");
    	resultFile.write(iToString(*((*it).pattern+2)).c_str());
    	resultFile.write("|");
    }
    resultFile.write(iToString(partial_ans.size()).c_str());
    ans_size=partial_ans.size();
    resultFile.write("|");
    std::vector<NTuple>::iterator partial_ans_beg=partial_ans.begin();
    std::vector<NTuple>::iterator partial_ans_end=partial_ans.end();
    for(std::vector<NTuple>::iterator it=partial_ans_beg;it!=partial_ans_end;it++){
    	std::vector<Binding>::iterator binding_beg=(*it).bindings.begin();
    	std::vector<Binding>::iterator binding_end=(*it).bindings.end();
    	for(std::vector<Binding>::iterator binding_it=binding_beg;binding_it!=binding_end;binding_it++){
    		resultFile.write((*binding_it).variableName.c_str());
    		resultFile.write("=");
    		resultFile.write((*binding_it).value.c_str());
    		if(binding_it!=(binding_end-1))
    			resultFile.write(",");
    	}
    	resultFile.write("|");
    }
    resultFile.close();
    std::cout << "End to write file:"  << fileName.c_str() << std::endl;
}
